package TCPMain;

import static TCPMain.Constant.ACTION_SendFolder;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import TCPMain.utils.DataUtil;

/**
 * 已经弃用，仅做学习使用
 * TCPService
 * 用于和Activity进行交互
 *
 *
 */
public class TCPService extends Service {
    private final String TAG = "TCPService";
    private final MyBinder binder = new MyBinder();
    private ExecutorService SocketPool;
    private Client FolderClient;//文件夹查看的Socket

    private int MaxDownload = 30;
    private DataUtil dataUtil = new DataUtil();//数据处理工具
    private ScheduledExecutorService scheduler;
    // 创建一个线程池来处理文件下载任务
    private final ExecutorService downloadPool = Executors.newFixedThreadPool(MaxDownload);


    // 定义一个内部类，继承自 Binder
    public class MyBinder extends Binder {
        // 允许客户端调用 Service 的方法
        public TCPService getService() {
            return TCPService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "Service onBind");
        return binder; // 返回 Binder 对象
    }

    @Override
    public void onCreate() {
        /**
         * 启动动服务：
         * 如果 Service 尚未运行，startService 方法会创建并启动 Service。
         * 如果 Service 已经运行，则 startService 方法不会重新创建 Service，但会调用其 onStartCommand 方法。
         */
        super.onCreate();
        Log.d(TAG, "Service onCreate");
        // 创建一个调度器来处理后台任务
        scheduler = Executors.newScheduledThreadPool(4);
        // 启动定期任务
        scheduler.scheduleAtFixedRate(this::processFileClients, 0, 1, TimeUnit.SECONDS);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "Service onStartCommand");
        // 后台任务
        new Thread(() -> {
            try {
                if (intent != null && intent.hasExtra("Task")) {
                    // 从 Intent 中获取数据
                    String jsonStr = intent.getStringExtra("Task");
                    String SERVER_IP = AllData.getSERVER_IP();
                    String username = AllData.getUsername();
                    String password = AllData.getPassword();
                    int SERVER_PORT = AllData.getSERVER_PORT();
                    Log.d(TAG, "Received JSON Object: " + jsonStr);
                    // 解析 JSON 字符串
                    JSONObject Task = new JSONObject(jsonStr);
                    /**
                     * 处理任务
                     */
                    //如果是文件夹查看请求，复用文件夹查看的Socket
                    if (Task.getString("Command").equals("SendFolder")) {
                        Log.d(TAG, "onStartCommand: SendFolder");
                        FolderClient = new Client();
                        JSONObject data = FolderClient.SendFolder(Task);
                        Log.d(TAG, "onendCommand: " + data);
                        AllData.setAllJsonData(data);
                        // 发送广播通知 Activity
                        Intent broadcastIntent = new Intent(ACTION_SendFolder);
                        broadcastIntent.putExtra("FolderData", data.toString());
                        LocalBroadcastManager.getInstance(TCPService.this).sendBroadcast(broadcastIntent);
                        //FolderClient.close();
                    }
                    //如果是文件的下载请求，新建文件的Socket，同时最多只能有MaxDownload个文件下载
                    else if (Task.getString("Command").equals("SendFile")) {
                        JSONObject DownData = dataUtil.GetData(jsonStr);
                        AllData.addWaitDownList(DownData);//加入数据到待下载队列
                        Log.d(TAG, "文件下载请求完成");
                    } else {
                        Log.d(TAG, "错误命令");
                    }
                }
            } catch (JSONException e) {
                throw new RuntimeException(e);
            }
        }).start();
        return START_STICKY;
    }
    /**
     * 执行文件下载队列
     * @throws JSONException
     */
    private void processFileClients() {
        List<JSONObject> waitDownList = AllData.getWaitDownList();
        Map<JSONObject, Client> fileClients = AllData.getFileClients();
//        Log.d(TAG, "执行文件下载队列");
        // 获取线程池状态
//        String TAG1="ThreadPoolExecutor";
        ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) downloadPool;
//        Log.d(TAG1, "-----------------------------------");
//        Log.d(TAG1, "获取当前线程池中的线程数: " + threadPoolExecutor.getPoolSize()); // 获取当前线程池中的线程数
//        Log.d(TAG1, "获取当前正在执行任务的线程数: " + threadPoolExecutor.getActiveCount()); // 获取当前正在执行任务的线程数
//        Log.d(TAG1, "获取任务队列中的任务数: " + threadPoolExecutor.getQueue().size()); // 获取任务队列中的任务数
//        Log.d(TAG1, "获取已完成的任务数: " + threadPoolExecutor.getCompletedTaskCount()); // 获取已完成的任务数
//        Log.d(TAG1, "获取已提交的任务总数: " + threadPoolExecutor.getTaskCount()); // 获取已提交的任务总数
//        Log.d(TAG1, "获取线程池曾经同时存在的最大线程数: " + threadPoolExecutor.getLargestPoolSize()); // 获取线程池曾经同时存在的最大线程数
//        Log.d(TAG1, "判断线程池是否已关闭: " + threadPoolExecutor.isShutdown()); // 判断线程池是否已关闭
//        Log.d(TAG1, "判断线程池是否已终止: " + threadPoolExecutor.isTerminated()); // 判断线程池是否已终止

        if (waitDownList == null || waitDownList.isEmpty()) {
            return;
        }
        //从待下载队列中取出文件下载请求的数据
        for(JSONObject jsonObject : waitDownList){
            //如果文件下载队列中存在该文件，则跳过该文件
            if (fileClients.containsKey(jsonObject)){
                continue;
            }
            //如果文件下载队列中不存在该文件，则创建文件下载线程
            else {
                //提交文件到下载队列
                AllData.removeWaitDownList(jsonObject);
                // 提交文件下载任务到线程池
                downloadPool.submit(() -> {
                    Client FileClient = new Client("60.215.128.117", AllData.getSERVER_PORT()+1);
                    try {
                        AllData.addFileClient(jsonObject, FileClient);
                        while (!Thread.currentThread().isInterrupted()) {
                            try {
                                FileClient.SendFile(jsonObject, new FileProgress());
                                break;
                            } catch (JSONException e) {
                                Log.w(TAG, "网络中断，5秒后重试...");
                                Thread.sleep(5000);
                            }
                        }
                    } catch (InterruptedException e) {
                        Log.w(TAG, "下载线程被中断");
                    } finally {
                        FileClient.close();
                    }
                });

            }
        }
//        Log.d(TAG, "执行文件下载队列完成");
        // 删除下载队列中已经下载完成的文件
        Iterator<Map.Entry<JSONObject, Client>> iterator = fileClients.entrySet().iterator();
        try{
            while (iterator.hasNext()) {
                Map.Entry<JSONObject, Client> entry = iterator.next();
                JSONObject jsonObject = entry.getKey();
                Client FileClient = entry.getValue();
                // 判断client是否关闭
                if (FileClient.isClose()) {
                    iterator.remove();
                    Log.d(TAG, "文件下载完成：" + jsonObject.getString("SendFileNames"));
                }
            }
        }catch (JSONException e){
            Log.e(TAG, "处理文件下载任务时发生错误", e);
        }

        // 关闭线程池（可选）
        // 如果文件下载任务完成后不再需要线程池，可以关闭它
        // downloadPool.shutdown();
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Service onDestroy");
    }

    // 定义一个方法供 Activity 调用
    public void doSomething() {
        Log.d(TAG, "Service doSomething called");
    }
}